package com.seng.resourcetycoon.services.impl;

import com.seng.resourcetycoon.core.enums.TowerState;
import com.seng.resourcetycoon.gui.models.ResourceTower;
import com.seng.resourcetycoon.gui.views.TowerGardItemView;
import com.seng.resourcetycoon.manager.GameEnvironment;
import com.seng.resourcetycoon.services.GamePlayService;
import com.seng.resourcetycoon.services.TowerManagementService;
import com.seng.resourcetycoon.util.Util;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.List;

public class TowerManagementServiceImpl implements TowerManagementService {

    private List<TowerGardItemView> activeTowers = new ArrayList<>();
    private Timeline timeLine;


    public TowerManagementServiceImpl() {
    }

    /**
     * Refreshes the view displaying the currently active towers.
     * This method clears the existing list of active towers, iterates through the game environment's
     * active towers, creates a new TowerGardItemView for each one, binds the corresponding tower data,
     * and adds the view to the active towers list.
     * No parameters are taken, and no value is returned.
     */
    private void refreshActiveView() {
        // Clear the current list of active towers
        activeTowers.clear();
        // Obtain the list of active towers from the game environment
        List<ResourceTower> selectedResourceTower = GameEnvironment.getInstance().getActiveTowers();
        for (ResourceTower resourceTower : selectedResourceTower) {
            // Create a new view item for the active tower
            TowerGardItemView towerGardItem = new TowerGardItemView();
            // Bind the tower data to the view item
            towerGardItem.bindData(resourceTower);
            // Add the bound view item to the active towers list
            activeTowers.add(towerGardItem);
        }
    }


    @Override
    public List<TowerGardItemView> getAndRefreshTowerCardItemView() {
        refreshActiveView();
        return activeTowers;
    }

    @Override
    public void reset() {
        List<ResourceTower> selectedResourceTower = GameEnvironment.getInstance().getActiveTowers();
        for (ResourceTower resourceTower : selectedResourceTower) {
            resourceTower.rest();
        }
    }

    /**
     * Resets all active resource towers in the game environment.
     * <p>
     * This method retrieves the list of currently active {@link ResourceTower} instances from
     * the singleton instance of {@link GameEnvironment}. It then iterates through this list,
     * invoking the {@code rest()} method on each tower. The purpose of this operation is to
     * reset or refresh the state of these towers according to their individual implementations.
     * </p>
     * <p>
     * Note: It is assumed that the {@code getActiveTowers()} method from {@link GameEnvironment}
     * provides a valid, non-null list of towers and that the {@code rest()} method on
     * {@link ResourceTower} is properly implemented to handle its specific reset logic without
     * requiring additional error handling within this method.
     * </p>
     *
     * @throws NullPointerException if an unexpected null value is encountered during the process,
     *                              typically due to environmental issues rather than this method's direct responsibility.
     */
    @Override
    public boolean updateSelectedTowerStateToDamaged() {
        try {
            List<ResourceTower> activeTowersList = GameEnvironment.getInstance().getActiveTowers();
            if (activeTowersList == null || activeTowersList.isEmpty()) {
                System.out.println("No active towers to damage.");
                return false;
            }
            ResourceTower selectedResourceTower = Util.improvedRandomElementOrDefault(activeTowersList, null);
            if (selectedResourceTower == null) {
                System.out.println("No tower selected to damage.");
                return false;
            }
            selectedResourceTower.setState(TowerState.DAMAGED);
            for (TowerGardItemView activeTowerView : activeTowers) {
                if (activeTowerView.refreshViewByResourceId(selectedResourceTower)) {
                    System.out.printf("View for tower %1s refreshed successfully.%n", selectedResourceTower.getId()+"\n");
                    return true;
                }
            }
        } catch (Exception e) {
            System.out.println("Error while damaging the tower.");
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void initialize(GamePlayService gamePlayService) {
        timeLine = new Timeline(
                new KeyFrame(Duration.millis(1),
                        event -> {
                            for (TowerGardItemView tower : activeTowers) {
                                tower.generateResource();
                            }
                        })
        );
        timeLine.setCycleCount(Timeline.INDEFINITE); // 循环执行
    }

    @Override
    public void begin() {
        timeLine.play();
    }

    @Override
    public void suspend() {
        if (timeLine != null) {
            timeLine.pause();
        }
    }

    @Override
    public void continueProcessing() {
        timeLine.play();
    }

    @Override
    public void cleanup(GamePlayService gamePlayService) {
        timeLine.stop();
    }

}
